﻿using PARK.Common.Enum;
using PARK.Common.Extension;
using PARK.Common.Filter;
using PARK.Dependency;
using PARK.DynamicApiController;
using PARK.FriendlyException;
using Mapster;
using Microsoft.AspNetCore.Mvc;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Yitter.IdGenerator;
using PARK.Common.Helper;
using PARK.JsonSerialization;
using PARK.Welfare.Interfaces.WelfareBill;
using PARK.Welfare.Entitys;
using PARK.Common.Core.Manager;
using PARK.Welfare.Entitys.Dto.WelfareBill;
using PARK.ClayObject;
using PARK.Common.Model.NPOI;
using PARK.Common.Configuration;
using PARK.DataEncryption;
using PARK.Welfare.Entitys.Dto.WelfareDetail;
using PARK.System.Interfaces.System;
using PARK.SubDev.Entitys.Dto;
using Microsoft.AspNetCore.Http;
using PARK.System.Interfaces.Common;
using PARK.CardAcct.Entitys;
using PARK.System.Entitys.Permission;

namespace PARK.Welfare.WelfareBill
{
    /// <summary>
    /// 福利发放记录服务
    /// </summary>
    [ApiDescriptionSettings(Tag = "Welfare", Name = "WelfareBill", Order = 200)]
    [Route("api/welfare/[controller]")]
    public class WelfareBillService : IWelfareBillService, IDynamicApiController, ITransient
    {
        private readonly ISqlSugarRepository<WelfareBillEntity> _welfareBillRepository;
        private readonly ISqlSugarRepository<WelfareDetailEntity> _welfareDetailRepository;
        private readonly IBillRullService _billRuleService;
        private readonly SqlSugarScope _db;
        private readonly IUserManager _userManager;
        private readonly IFileService _fileService;

        /// <summary>
        /// 初始化一个<see cref="WelfareBillService"/>类型的新实例
        /// </summary>
        public WelfareBillService(
            ISqlSugarRepository<WelfareBillEntity> welfareBillRepository,
            ISqlSugarRepository<WelfareDetailEntity> welfareDetailRepository,
            IBillRullService billRuleService,
            IFileService fileService,
            IUserManager userManager)
        {
            _welfareBillRepository = welfareBillRepository;
            _db = _welfareBillRepository.Context;
            _fileService = fileService;
            _welfareDetailRepository = welfareDetailRepository;
            _billRuleService = billRuleService;
            _userManager = userManager;
        }

        /// <summary>
        /// 获取福利发放
        /// </summary>
        /// <param name="id">参数</param>
        /// <returns></returns>
        [HttpGet("{id}")]
        public async Task<dynamic> GetInfo(string id)
        {
            var entity = await _db.Queryable<WelfareBillEntity>().FirstAsync(p => p.BillId == id);
            var output = entity.Adapt<WelfareBillInfoOutput>();
            var welfareDetailList = await _db.Queryable<WelfareDetailEntity>().Where(w => w.BillId == entity.BillId).ToListAsync();
            output.welfareDetailList = welfareDetailList.Adapt<List<WelfareDetailInfoOutput>>();
            return output;
        }

        /// <summary>
		/// 获取福利发放记录列表
		/// </summary>
		/// <param name="input">请求参数</param>
		/// <returns></returns>
        [HttpGet("")]
        public async Task<dynamic> GetList([FromQuery] WelfareBillListQueryInput input)
        {
            var userInfo = await _userManager.GetUserInfo();
            var sidx = input.sidx == null ? "DbDate" : input.sidx;

            //发放日期
            List<string> queryBillDate = input.inputBillDate != null ? input.inputBillDate.Split(',').ToObeject<List<string>>() : null;
            DateTime? startBilldate = queryBillDate != null ? Ext.GetDateTime(queryBillDate.First()) : null;
            DateTime? endBilldate = queryBillDate != null ? Ext.GetDateTime(queryBillDate.Last()) : null;
            //发放时段
            List<string> querybegendDate = input.inputbegendDate != null ? input.inputbegendDate.Split(',').ToObeject<List<string>>() : null;
            DateTime? startbegdate = querybegendDate != null ? Ext.GetDateTime(querybegendDate.First()) : null;
            DateTime? endenddate = querybegendDate != null ? Ext.GetDateTime(querybegendDate.Last()) : null;
            var data = await _db.Queryable<WelfareBillEntity>()
                .Where(p => p.CompanyId.Equals(userInfo.companyId))//权限
                //关键字查询
                .WhereIF(!input.keyword.IsNullOrEmpty(), p => p.BillCode.Contains(input.keyword) || p.AuditUserName.Contains(input.keyword) || p.WageRows.Equals(input.keyword) || p.Wagetotal.Equals(input.keyword))
                //发放日期查询
                .WhereIF(queryBillDate != null, a => a.BillDate >= new DateTime(startBilldate.ToDate().Year, startBilldate.ToDate().Month, startBilldate.ToDate().Day, 0, 0, 0))
                .WhereIF(queryBillDate != null, a => a.BillDate <= new DateTime(endBilldate.ToDate().Year, endBilldate.ToDate().Month, endBilldate.ToDate().Day, 23, 59, 59))
                //发放时段查询
                .WhereIF(querybegendDate != null, a => a.BegDate >= new DateTime(startbegdate.ToDate().Year, startbegdate.ToDate().Month, startbegdate.ToDate().Day, 0, 0, 0))
                .WhereIF(querybegendDate != null, a => a.EndDate <= new DateTime(endenddate.ToDate().Year, endenddate.ToDate().Month, endenddate.ToDate().Day, 23, 59, 59))
                .Select(it => new WelfareBillListOutput
                {
                    billId = it.BillId,
                    billCode = it.BillCode,
                    billMonth = Convert.ToDateTime(it.BillMonth).ToString("yyyy-MM"),
                    billDate = Convert.ToDateTime(it.BillDate).ToString("yyyy-MM-dd"),
                    begDate = Convert.ToDateTime(it.BegDate).ToString("yyyy-MM-dd"),
                    endDate = Convert.ToDateTime(it.EndDate).ToString("yyyy-MM-dd"),
                    wagetotal = it.Wagetotal,
                    wageRows = it.WageRows,
                    summary = it.Summary,
                    IsAudit = it.IsAudit,
                    AuditUser = it.AuditUser,
                    AuditUserName = it.AuditUserName,
                    AuditDate = Convert.ToDateTime(it.AuditDate).ToString("yyyy-MM-dd HH:mm:ss"),
                    DbDate = Convert.ToDateTime(it.DbDate).ToString("yyyy-MM-dd HH:mm:ss"),
                }).MergeTable().OrderBy(sidx + " " + input.sort).ToPagedListAsync(input.currentPage, input.pageSize);
            return PageResult<WelfareBillListOutput>.SqlSugarPageResult(data);
        }

        /// <summary>
        /// 新建福利发放
        /// </summary>
        /// <param name="input">参数</param>
        /// <returns></returns>
        [HttpPost("")]
        public async Task Create([FromBody] WelfareBillCrInput input)
        {
            var userInfo = await _userManager.GetUserInfo();
            var entity = input.Adapt<WelfareBillEntity>();
            entity.BillId = YitIdHelper.NextId().ToString();
            entity.BillCode = await _billRuleService.GetBillNumber("flff");
            entity.BillMonth = Convert.ToDateTime(entity.BillMonth).AddDays(1);

            DateTime dt = DateTime.Parse(Convert.ToDateTime(entity.BillMonth).ToString("yyyy-MM-dd") + " 00:00:00");
            //获得本月月初时间
            var startMonth = dt.AddDays(1 - dt.Day);
            //获得本月月末时间
            DateTime s = DateTime.Parse(Convert.ToDateTime(entity.BillMonth).ToString("yyyy-MM-dd") + " 23:59:59");
            DateTime ss = s.AddDays(1 - s.Day);
            var endMonth = ss.AddMonths(1).AddDays(-1);

            entity.BegDate = startMonth;
            entity.EndDate = endMonth;
            entity.CreateUser = userInfo.userId;
            entity.CreateUserName = userInfo.userName;
            entity.CreateDate = DateTime.Now;
            entity.CompanyId = userInfo.companyId;
            entity.CompanyName = userInfo.companyName;
            try
            {
                //开启事务
                _db.BeginTran();
                int _WageRows = 0;
                decimal _Wagetotal = 0;
                var welfareDetailEntityList = input.welfareDetailList.Adapt<List<WelfareDetailEntity>>();
                var welfarelist = new List<WelfareDetailEntity>();
                if (welfareDetailEntityList != null)
                {
                    foreach (var item in welfareDetailEntityList)
                    {
                        _WageRows++;
                        _Wagetotal += item.Amount;
                        item.Detailsid = YitIdHelper.NextId().ToString();
                        item.BillId = entity.BillId;
                        item.BillCode = entity.BillCode;
                        item.BegDate = entity.BegDate;
                        item.EndDate = entity.EndDate;
                        item.Balance = item.Amount;
                        item.IsAccounted = 0;
                        item.BillDate = entity.BillDate;
                        item.DbDate = entity.BillDate;
                        item.BussKind = 1;
                        item.CompanyId = userInfo.companyId;
                        item.CompanyName = userInfo.companyName;
                        welfarelist.Add(item);
                    }
                    if (welfarelist != null && welfarelist.Count > 0)
                        await _db.Insertable(welfarelist).ExecuteCommandAsync();
                }
                //新增福利发放记录
                entity.WageRows = _WageRows;
                entity.Wagetotal = _Wagetotal;
                var newEntity = await _db.Insertable(entity).IgnoreColumns(ignoreNullColumn: true).ExecuteReturnEntityAsync();
                //关闭事务
                _db.CommitTran();
            }
            catch (Exception ex)
            {
                //回滚事务
                _db.RollbackTran();
                throw PARKException.Oh(ErrorCode.COM1000);
            }
        }

        /// <summary>
        /// 更新福利发放
        /// </summary>
        /// <param name="id">主键</param>
        /// <param name="input">参数</param>
        /// <returns></returns>
        [HttpPut("{id}")]
        public async Task Update(string id, [FromBody] WelfareBillUpInput input)
        {
            var userInfo = await _userManager.GetUserInfo();
            var entity = input.Adapt<WelfareBillEntity>();
            entity.BillMonth = Convert.ToDateTime(entity.BillMonth).AddDays(1);

            DateTime dt = DateTime.Parse(Convert.ToDateTime(entity.BillMonth).ToString("yyyy-MM-dd") + " 00:00:00");
            //获得本月月初时间
            var startMonth = dt.AddDays(1 - dt.Day);
            //获得本月月末时间
            DateTime s = DateTime.Parse(Convert.ToDateTime(entity.BillMonth).ToString("yyyy-MM-dd") + " 23:59:59");
            DateTime ss = s.AddDays(1 - s.Day);
            var endMonth = ss.AddMonths(1).AddDays(-1);

            entity.BegDate = startMonth;
            entity.EndDate = endMonth;
            try
            {
                //开启事务
                _db.BeginTran();

                //更新福利发放记录
                //await _db.Updateable(entity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();

                //清空原有数据
                await _db.Deleteable<WelfareDetailEntity>().Where(u => u.BillId == id).ExecuteCommandAsync();
                int _WageRows = 0;
                decimal _Wagetotal = 0;
                //新增新数据
                var welfareDetailEntityList = input.welfareDetailList.Adapt<List<WelfareDetailEntity>>();
                var welfarelist = new List<WelfareDetailEntity>();
                if (welfareDetailEntityList != null)
                {
                    foreach (var item in welfareDetailEntityList)
                    {
                        //item.Detailsid = YitIdHelper.NextId().ToString();
                        //item.BillId = entity.BillId;
                        _WageRows++;
                        _Wagetotal += item.Amount;
                        item.Detailsid = YitIdHelper.NextId().ToString();
                        item.BillId = entity.BillId;
                        item.BillCode = entity.BillCode;
                        item.BegDate = entity.BegDate;
                        item.EndDate = entity.EndDate;
                        item.Balance = item.Amount;
                        item.IsAccounted = 0;
                        item.BillDate = entity.BillDate;
                        item.DbDate = entity.BillDate;
                        item.BussKind = 1;
                        item.CompanyId = userInfo.companyId;
                        item.CompanyName = userInfo.companyName;
                        welfarelist.Add(item);
                    }
                    if (welfarelist != null && welfarelist.Count > 0)
                        await _db.Insertable(welfarelist).ExecuteCommandAsync();
                }
                entity.WageRows = _WageRows;
                entity.Wagetotal = _Wagetotal;
                //更新福利发放记录
                var newEntity = await _db.Updateable(entity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
                //关闭事务
                _db.CommitTran();
            }
            catch (Exception)
            {
                //回滚事务
                _db.RollbackTran();
                throw PARKException.Oh(ErrorCode.COM1001);
            }
        }
        /// <summary>
        /// 审核福利发放
        /// </summary>
        /// <returns></returns>
        [HttpPost("WelAudit")]
        public async Task WelAudit([FromBody] WelfareBillCrInput input)
        {
            var userInfo = await _userManager.GetUserInfo();
            var entity = await _db.Queryable<WelfareBillEntity>().FirstAsync(p => p.BillId == input.billId);
            _ = entity ?? throw PARKException.Oh(ErrorCode.COM1005);
            try
            {
                //开启事务
                _db.BeginTran();
                entity.IsAudit = 1;
                entity.AuditUser = userInfo.userId;
                entity.AuditUserName = userInfo.userName;
                entity.AuditDate = DateTime.Now;
                entity.CompanyId = userInfo.companyId;
                entity.CompanyName = userInfo.companyName;
                var detaillist = await _db.Queryable<WelfareDetailEntity>().Where(p => p.BillId == input.billId).ToListAsync();
                foreach (var item in detaillist)
                {
                    item.IsAccounted = 1;
                    item.AccountedDate = DateTime.Now;
                    item.CompanyId = userInfo.companyId;
                    item.CompanyName = userInfo.companyName;
                    await _db.Updateable(item).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
                    var _Employee = await _db.Queryable<EmployeeEntity>().FirstAsync(t => t.EmployeeId == item.EmployeeId);
                    _Employee.WelfareBalance += item.Amount;
                    await _db.Updateable(_Employee).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
                }
                //更新福利发放记录
                await _db.Updateable(entity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
                //关闭事务
                _db.CommitTran();
            }
            catch (Exception)
            {
                //回滚事务
                _db.RollbackTran();
                throw PARKException.Oh(ErrorCode.COM1001);
            }
        }
        /// <summary>
        /// 删除福利发放
        /// </summary>
        /// <returns></returns>
        [HttpDelete("{id}")]
        public async Task Delete(string id)
        {
            var entity = await _db.Queryable<WelfareBillEntity>().FirstAsync(p => p.BillId == id);
            _ = entity ?? throw PARKException.Oh(ErrorCode.COM1005);
            try
            {
                //开启事务
                _db.BeginTran();

                //删除福利发放记录
                await _db.Deleteable<WelfareBillEntity>().Where(d => d.BillId == id).ExecuteCommandAsync();

                //清空子表数据
                await _db.Deleteable<WelfareDetailEntity>().Where(u => u.BillId == id).ExecuteCommandAsync();

                //关闭事务
                _db.CommitTran();
            }
            catch (Exception)
            {
                //回滚事务
                _db.RollbackTran();
                throw PARKException.Oh(ErrorCode.COM1002);
            }
        }

        #region 导出Excel
        /// <summary>
        /// 获取发放记录无分页列表
        /// </summary>
        /// <param name="input">请求参数</param>
        /// <returns></returns>
        [NonAction]
        public async Task<dynamic> GetNoPagingList([FromQuery] WelfareBillListQueryInput input)
        {
            var userInfo = await _userManager.GetUserInfo();
            var sidx = input.sidx == null ? "billId" : input.sidx;
            var data = await _db.Queryable<WelfareBillEntity>()
                .Select(it => new WelfareBillListOutput
                {
                    billId = it.BillId,
                    billCode = it.BillCode,
                    billDate = Convert.ToDateTime(it.BillDate).ToString("yyyy-MM-dd"),
                    begDate = Convert.ToDateTime(it.BegDate).ToString("yyyy-MM-dd"),
                    endDate = Convert.ToDateTime(it.EndDate).ToString("yyyy-MM-dd"),
                    wagetotal = it.Wagetotal,
                    wageRows = it.WageRows,
                    summary = it.Summary,
                    IsAudit = it.IsAudit,
                    AuditUser = it.AuditUser,
                    AuditUserName = it.AuditUserName,
                    AuditDate = Convert.ToDateTime(it.AuditDate).ToString("yyyy-MM-dd HH:mm:ss"),
                    DbDate = Convert.ToDateTime(it.DbDate).ToString("yyyy-MM-dd HH:mm:ss"),
                }).MergeTable().OrderBy(sidx + " " + input.sort).ToListAsync();
            return data;
        }

        /// <summary>
        /// 导出发放记录
        /// </summary>
        /// <param name="input">请求参数</param>
        /// <returns></returns>
        [HttpGet("Actions/Export")]
        public async Task<dynamic> Export([FromQuery] WelfareBillListQueryInput input)
        {
            var userInfo = await _userManager.GetUserInfo();
            var exportData = new List<WelfareBillListOutput>();
            var exportDataNew = new List<WelfareBillListOutput>();

            var entity = input.Adapt<WelfareBillEntity>();

            if (input.dataType == 0)
            {
                var data = Clay.Object(await this.GetList(input));
                exportData = data.Solidify<PageResult<WelfareBillListOutput>>().list;
            }
            else
            {
                exportData = await this.GetNoPagingList(input);
            }

            foreach (WelfareBillListOutput item in exportData)
            {
                exportDataNew.Add(item);
            }

            List<ParamsModel> paramList = "[{\"value\":\"单据编号\",\"field\":\"billId\"},{\"value\":\"单据日期\",\"field\":\"billDate\"},{\"value\":\"开始时段\",\"field\":\"begDate\"},{\"value\":\"截止时段\",\"field\":\"endDate\"},{\"value\":\"福利总额\",\"field\":\"wagetotal\"},{\"value\":\"福利总条数\",\"field\":\"wageRows\"},{\"value\":\"确认状态\",\"field\":\"IsAudit\"},{\"value\":\"确认者姓名\",\"field\":\"AuditUserName\"},{\"value\":\"确认时间\",\"field\":\"AuditDate\"},{\"value\":\"备注信息\",\"field\":\"summary\"},]".ToList<ParamsModel>();
            ExcelConfig excelconfig = new ExcelConfig();
            excelconfig.FileName = userInfo.organizeName + "_" + "福利发放记录" + DateTime.Now.ToString("yyyyMMddHHmmss") + ".xls";
            excelconfig.HeadFont = "微软雅黑";
            excelconfig.HeadPoint = 10;
            excelconfig.IsAllSizeColumn = true;
            excelconfig.ColumnModel = new List<ExcelColumnModel>();
            List<string> selectKeyList = input.selectKey.Split(',').ToList();
            foreach (var item in selectKeyList)
            {
                var isExist = paramList.Find(p => p.field == item);
                if (isExist != null)
                {
                    excelconfig.ColumnModel.Add(new ExcelColumnModel() { Column = isExist.field, ExcelColumn = isExist.value });
                }
            }
            var addPath = FileVariable.TemporaryFilePath + excelconfig.FileName;
            ExcelExportHelper<WelfareBillListOutput>.Export(exportDataNew, excelconfig, addPath);
            var fileName = _userManager.UserId + "|" + addPath + "|xls";
            var output = new
            {
                name = excelconfig.FileName,
                //url = "wwwroot/Resources/TemporaryFile/" + excelconfig.FileName
                url = "api/file/Download?encryption=" + DESCEncryption.Encrypt(fileName, "JNPF") //"wwwroot/Template/TemporaryFile/" + excelconfig.FileName //
            };
            return output;
        }
        #endregion

        #region 导入
        /// <summary>
        /// 模板下载
        /// </summary>
        [HttpGet("TemplateDownloadwel")]
        public dynamic TemplateDownloadwel()
        {
            var filePath = FileVariable.TemplateFilePath + "福利信息模板.xls";//模板路径
            var addFilePath = FileVariable.TemporaryFilePath + "福利信息模板.xls";//保存路径
            if (!FileHelper.IsExistFile(addFilePath))
            {
                List<ExcelTemplateModel> templateList = new List<ExcelTemplateModel>();
                ExcelExportHelper<ExcelTemplateModel>.Export(templateList, filePath, addFilePath);
            }
            return new { name = "福利信息模板.xls", url = "api/File/Download?encryption=" + DESCEncryption.Encrypt(_userManager.UserId + "|福利信息模板.xls", "JNPF") };
        }

        /// <summary>
        /// 导入预览
        /// </summary>
        /// <returns></returns>
        [HttpGet("ImportPreviewwel")]
        public async Task<dynamic> ImportPreviewwel(string fileName)
        {
            try
            {
                var userInfo = await _userManager.GetUserInfo();

                var filePath = FileVariable.TemporaryFilePath;
                var savePath = filePath + fileName;
                var excelData = ExcelImportHelper.ToDataTable(savePath);

                List<WelfareDetailListOutput> WelfareDetailListFailResult = new List<WelfareDetailListOutput>();
                List<CheckDateerrOutput> FailResult = new List<CheckDateerrOutput>();
                WelfareDetailListOutput put = null;
                foreach (var item in excelData.Columns)
                {
                    excelData.Columns[item.ToString()].ColumnName = GetFiledEncodestu(item.ToString());
                }
                //卡户
                var _Employeelist = await _db.Queryable<EmployeeEntity>().ToListAsync();
                //部门
                var _Organizelist = await _db.Queryable<OrganizeEntity>().ToListAsync();
                //删除文件
                //FileHelper.DeleteFile(savePath);
                //返回结果
                if (excelData != null && excelData.Rows.Count > 0)
                {
                    var _iserr = 0;
                    var _msg = "";
                    for (int i = 0; i < excelData.Rows.Count; i++)
                    {
                        _iserr = 0;
                        _msg = "";
                        put = new WelfareDetailListOutput();
                        put.jobNo = excelData.Rows[i]["jobNo"].ToString();

                        //验证卡户
                        var Employee = _Employeelist.Where(p => p.JobNum.Equals(put.jobNo)).ToList();
                        if (Employee != null && Employee.Count > 0)
                        {
                            put.employeeId = Employee[0].EmployeeId;
                            put.jobNo = Employee[0].JobNum;
                            put.reallName = Employee[0].RealName;
                            put.departId = Employee[0].DepartId;
                            put.departName = Employee[0].DepartName;
                            put.cardNo = Employee[0].CardNo;
                        }
                        else
                        {
                            _msg += "[人员] 系统中不存在;";
                            _iserr++;
                        }
                        try
                        {
                            put.amount = Convert.ToDecimal(excelData.Rows[i]["amount"]);
                        }
                        catch (Exception)
                        {
                            _msg += "[金额] 格式不正确;";
                            _iserr++;
                        }
                        put.CompanyId = userInfo.companyId;
                        put.CompanyName = userInfo.companyName;
                        if (_iserr > 0)
                        {
                            FailResult.Add(new CheckDateerrOutput()
                            {
                                rowNo = (i + 1).ToString(),
                                errorMsg = _msg
                            });
                        }
                        else
                        {
                            WelfareDetailListFailResult.Add(put);
                        }
                    }
                }
                return new { dataRow = WelfareDetailListFailResult, errRow = FailResult };
            }
            catch (Exception e)
            {

                throw PARKException.Oh(ErrorCode.D1801);
            }
        }
        /// <summary>
        /// 获取字段编码
        /// </summary>
        /// <param name="filed"></param>
        /// <returns></returns>
        private string GetFiledEncodestu(string filed)
        {
            switch (filed)
            {
                case "员工编号":
                    return "jobNo";
                case "姓名":
                    return "reallName";
                case "金额":
                    return "amount";
                case "部门名称":
                    return "departName";
                default:
                    return "";
            }
        }
        /// <summary>
        /// 上传文件
        /// </summary>
        /// <returns></returns>
        [HttpPost("Uploaderwel")]
        public async Task<dynamic> Uploaderwel(IFormFile file)
        {
            return await _fileService.Uploader("", file);
        }
        #endregion
    }
}
